package com.ztmao.shortlink.project.listener.idempotency;

import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 幂等性切面
 */
@Aspect
public class IdempotencyAspect {
    private MessageQueueIdempotentHandler messageQueueIdempotentHandler;
    public IdempotencyAspect(MessageQueueIdempotentHandler messageQueueIdempotentHandler) {
        this.messageQueueIdempotentHandler = messageQueueIdempotentHandler;
    }
    @Around("@annotation(com.ztmao.shortlink.project.listener.idempotency.IdempotencyAnnotation)")
    public Object idempotency(ProceedingJoinPoint joinPoint) throws Throwable {
          // 幂等性校验逻辑
        MessageExt message = (MessageExt)joinPoint.getArgs()[0];
        String msgId = message.getMsgId();
        // 保存消息消费中状态
        if(messageQueueIdempotentHandler.isMessageBeingConsumed(msgId)){
            //正在消费中，抛出异常触发消息重试
            throw new RuntimeException("消息正在消费中，请稍后重试");
        }
        // 判断消息是否已经消费
        if(messageQueueIdempotentHandler.isAccomplish(msgId)){
            // 已经消费过，直接返回
            return null;
        }

        try{
            Object result = joinPoint.proceed();
            // 消息消费成功，保存消息消费完成状态
            messageQueueIdempotentHandler.setAccomplish(msgId);
            return result;
        }catch (Exception e){
            //删除消息消费中状态
            messageQueueIdempotentHandler.delMessageProcessed(msgId);
            //出现异常，抛出异常，触发消息重试
            throw new RuntimeException("消息消费失败，请稍后重试");
        }

    }
}
